MAPS

Most Liveable Cities

Dot Map

Photo by Alex Rainer on Unsplash

Photo by Alex Rainer on Unsplash

The streets of Vienna are paved with culture, the streets of other cities with asphalt…
— Karl Kraus


Ingest

city ranks

Wrangle

enrich with coordinates

df <- df %>% select(Rank, City, Country)

all_cities <- read.csv("archetypes/most-liveable-cities/ne_10m_populated_places.csv", header = TRUE, stringsAsFactors = FALSE, encoding = "utf-8")
all_cities <- all_cities %>% select(NAME, NAMEASCII, ADM0NAME, LATITUDE, LONGITUDE)

df_coords <- merge(df, all_cities, by.x = c("City", "Country"), by.y = c("NAMEASCII", "ADM0NAME"))
head(df_coords, n = 10)

Wrangle

random sample for labels

sample_labels <- sample_n(df_coords, 25)
sample_labels

Analyze

create bin groups by rank, and labels for legend

df_bins <- df_coords %>% mutate(GROUP = ntile(df_coords$Rank, 6))
head(df_bins, n = 10)
df_bin_labels <- df_bins %>%
  group_by(GROUP) %>%
  summarise(
    bmin = min(Rank, na.rm = T),
    bmax = max(Rank, na.rm = T),
    count = n()
  ) %>%
  mutate(label = paste0("[ ", bmin, "-", bmax, " ]"))

# df_bin_labels

Base map

natural earth

ne_world <- ne_countries(scale = "small", returnclass = "sf")
ne_world <- filter(ne_world, iso_a3 != "ATA")

View

cities, ranks, and labels

theme_opts <- theme(
  text = element_text(family = "inconsolata"), 
  plot.title = element_text(color = "black", size = 14, face = "bold", family = "inconsolata"),
  plot.subtitle = element_text(color = "black", size = 12, family = "inconsolata"),
  plot.caption = element_text(color = "#555555", size = 8, family = "inconsolata"),
  plot.background = element_blank(),
  panel.grid = element_blank(),
  panel.grid.major = element_blank(),
  panel.grid.minor = element_blank(),
  panel.background=element_rect(fill="white", colour="white"),
  panel.border = element_blank(),
  axis.text = element_blank(),
  axis.line = element_blank(),
  axis.ticks = element_blank(),
  axis.title = element_blank(),
  legend.position = "top",
  legend.title = element_blank()
)

bin_palette <- c(
  "1" = "#254055", # most liveable
  "2" = "#7597b4",
  "3" = "#9ac4b8",
  "4" = "#c1cbba",
  "5" = "#e2d0ae",
  "6" = "#dba63b"  # least liveable
)

v1 <- ggplot(data = ne_world) +
  geom_sf(fill="#d9e0e5", color="white", size = 0.5) +
  geom_point( data = df_bins, aes(x=LONGITUDE, y=LATITUDE, fill = as.factor(GROUP)), shape = 21, size = 2, color = "#333333") +
  geom_text_repel(data = sample_labels, aes(x = LONGITUDE, y = LATITUDE, label = paste0(City, " [ ", Rank, " ]")), 
                  size = 4, hjust = 0.5, vjust = 0.5, family = "inconsolata", fontface = "bold",
                  seed = 42, force = 5, force_pull = 0, box.padding = 0.75, min.segment.length = 0, direction = "y", 
                  color = "black", bg.color = "white", bg.r = 0.15) +
  scale_fill_manual(values = bin_palette, labels = df_bin_labels$label) +
  theme_bw() +
  labs(x=NULL,
       y=NULL,
       title = "Quality of Living City Ranking", 
       subtitle="color by rank group") +
  theme_opts

girafe(ggobj = v1, width_svg = 16, height_svg = 8.25,
       options = list(opts_sizing(rescale = TRUE, width = 1.0)))

References

Citations and data sources

  • Narrative: The Economist, Graphic detail, GO
  • Data: Mercer, Quality of living city ranking 2019, GO